import { useEffect, useRef, useState } from 'react';
import Chart from '@/lib/chart';
import { useQuery } from '@tanstack/react-query';
import { queryNginxLogsWebsiteAccessCountByDay } from '@/services/api';
import type { INginxLogsWebsiteAccessCountByDay } from '@/interfaces';
import type { ChartData, ChartOptions } from 'chart.js';
import type { IDateTimeHeaderOptions } from '@/app/[locale]/admin/home/date-time-header';
import DateTimeHeader from '@/app/[locale]/admin/home/date-time-header';
import Alert from '@/app/[locale]/alert/alert';
import AlertLoad from '@/app/[locale]/alert/load';
import dayjs from 'dayjs';
import useToast from '@/hooks/useToast';
import { calculateDateTimeRange } from '@/lib/tool';
import type { PrefixedTTranslatedFields } from '@/lib/dictionaries';

export default function WebsiteAccessCounts({
  translatedFields,
}: {
  translatedFields: PrefixedTTranslatedFields<'homeAdminPage'>;
}) {
  const canvas = useRef<HTMLCanvasElement>(null);
  const chartRef = useRef<Chart<'line', any, any>>();
  const [params, setParams] = useState({
    ...calculateDateTimeRange(),
  });
  const [options, setOptions] = useState<Partial<IDateTimeHeaderOptions>>({
    activeOptions: {
      custom: false,
      toDay: true,
      yesterday: false,
      d3: false,
      d7: false,
      d15: false,
      d30: false,
    },
    refreshOptions: {
      isLoading: false,
    },
  });
  const { show } = useToast();

  const queryNginxLogsWebsiteAccessCountByDayQuery = useQuery(
    ['/nginx', '/logs', '/website', '/access-count-by-day', params],
    async (context) => {
      return (await queryNginxLogsWebsiteAccessCountByDay({
        query: context.queryKey[4] as any,
      })) as INginxLogsWebsiteAccessCountByDay;
    },
  );

  useEffect(() => {
    const current = canvas.current;
    const content = queryNginxLogsWebsiteAccessCountByDayQuery.data;
    if (current && content) {
      const labels = content.dates;
      const values = Object.values(content.ranges);
      const data = {
        labels,
        datasets: [
          {
            label: translatedFields.visits,
            data: values,
            pointRadius: 6,
            pointHoverRadius: 10,
          },
        ],
      } as ChartData<'line'>;
      const options = {
        responsive: true,
        scales: {
          x: {
            display: true,
            title: {
              display: false,
            },
            ticks: {
              maxTicksLimit: 7,
              callback: (value: string | number, index: number) => {
                if (index % 2 === 0) {
                  return labels[index];
                } else {
                  return '';
                }
              },
            },
          },
          y: {
            display: true,
            title: {
              display: false,
            },
          },
        },
      } as ChartOptions<'line'>;

      chartRef.current = new Chart(current, {
        type: 'line',
        data,
        options,
      });
    }

    return () => {
      if (current) {
        chartRef.current?.destroy();
      }
    };
  }, [queryNginxLogsWebsiteAccessCountByDayQuery.data]);

  function onUpdate(configs: {
    startDateTime: string;
    endDateTime: string;
    activeOptions?: IDateTimeHeaderOptions['activeOptions'];
  }) {
    setParams({
      ...params,
      startDateTime: configs.startDateTime,
      endDateTime: configs.endDateTime,
    });
    setOptions({
      ...options,
      activeOptions: { ...configs.activeOptions },
    });
  }

  function onClickToDay() {
    const { startDateTime, endDateTime } = calculateDateTimeRange();
    onUpdate({
      startDateTime,
      endDateTime,
      activeOptions: {
        toDay: true,
      },
    });
  }

  function onClickYesterday() {
    const { startDateTime, endDateTime } = calculateDateTimeRange(1);
    onUpdate({
      startDateTime,
      endDateTime,
      activeOptions: {
        yesterday: true,
      },
    });
  }

  function onClick3D() {
    const { startDateTime, endDateTime } = calculateDateTimeRange(3);
    onUpdate({
      startDateTime,
      endDateTime,
      activeOptions: {
        d3: true,
      },
    });
  }

  function onClick7D() {
    const { startDateTime, endDateTime } = calculateDateTimeRange(7);
    onUpdate({
      startDateTime,
      endDateTime,
      activeOptions: {
        d7: true,
      },
    });
  }

  function onClick15D() {
    const { startDateTime, endDateTime } = calculateDateTimeRange(15);
    onUpdate({
      startDateTime,
      endDateTime,
      activeOptions: {
        d15: true,
      },
    });
  }

  function onClick30D() {
    const { startDateTime, endDateTime } = calculateDateTimeRange(30);
    onUpdate({
      startDateTime,
      endDateTime,
      activeOptions: {
        d30: true,
      },
    });
  }

  function onClickCustom(startDateValue: string, endDateValue: string) {
    if (!startDateValue || !endDateValue) {
      show({
        type: 'DANGER',
        message: translatedFields.customDateNotSelected,
      });
      return;
    }

    const startDate = dayjs(startDateValue);
    const endDate = dayjs(endDateValue);
    if (endDate.isBefore(startDate)) {
      show({
        type: 'DANGER',
        message: translatedFields.invalidCustomDateFormat,
      });
      return;
    }

    const intervalDays = endDate.diff(startDate, 'day');
    const { startDateTime, endDateTime } = calculateDateTimeRange(intervalDays);
    onUpdate({
      startDateTime,
      endDateTime,
      activeOptions: {
        custom: true,
      },
    });
  }

  async function onClickRefresh() {
    try {
      setOptions({
        ...options,
        refreshOptions: {
          isLoading: true,
        },
      });

      await queryNginxLogsWebsiteAccessCountByDayQuery.refetch();
      show({
        type: 'SUCCESS',
        message: translatedFields.refreshCompleted,
      });
    } catch (e) {
      show({
        type: 'DANGER',
        message: e,
      });
    } finally {
      setOptions({
        ...options,
        refreshOptions: {
          isLoading: false,
        },
      });
    }
  }

  return (
    <div className="card">
      <div className="card-header bg-transparent">
        <DateTimeHeader
          options={{
            clickOptions: {
              onClickCustom,
              onClickRefresh,
              onClickToDay,
              onClickYesterday,
              onClick3D,
              onClick7D,
              onClick15D,
              onClick30D,
            },
            activeOptions: options.activeOptions!,
            refreshOptions: options.refreshOptions!,
          }}
          translatedFields={translatedFields}
        />
      </div>
      <div className="card-body">
        {queryNginxLogsWebsiteAccessCountByDayQuery.data && (
          <div>
            <canvas ref={canvas}></canvas>
          </div>
        )}

        {queryNginxLogsWebsiteAccessCountByDayQuery.isError && (
          <Alert
            message={queryNginxLogsWebsiteAccessCountByDayQuery.error}
            type="error"
          />
        )}

        {queryNginxLogsWebsiteAccessCountByDayQuery.isLoading && <AlertLoad />}
      </div>
    </div>
  );
}
